using CollabApp.Domain.Entities.Game;

namespace CollabApp.Domain.Services.Game;

/// <summary>
/// 游戏玩法服务接口
/// 负责处理游戏核心玩法逻辑，包括移动、攻击、收集等游戏行为
/// </summary>
public interface IGamePlayService
{
    /// <summary>
    /// 处理玩家移动
    /// 验证移动的合法性，更新玩家位置，检测碰撞和边界
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="moveCommand">移动命令</param>
    /// <returns>移动处理结果</returns>
    Task<MoveResult> ProcessPlayerMoveAsync(Guid gameId, Guid playerId, MoveCommand moveCommand);

    /// <summary>
    /// 处理玩家攻击行为
    /// 验证攻击条件，计算伤害，更新游戏状态
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="attackerId">攻击者标识</param>
    /// <param name="attackCommand">攻击命令</param>
    /// <returns>攻击处理结果</returns>
    Task<AttackResult> ProcessPlayerAttackAsync(Guid gameId, Guid attackerId, AttackCommand attackCommand);

    /// <summary>
    /// 处理物品收集
    /// 验证收集条件，更新玩家库存，移除地图物品
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="itemId">物品标识</param>
    /// <returns>收集处理结果</returns>
    Task<CollectResult> ProcessItemCollectionAsync(Guid gameId, Guid playerId, Guid itemId);

    /// <summary>
    /// 使用道具/技能
    /// 验证使用条件，应用道具效果，更新冷却时间
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="skillCommand">技能使用命令</param>
    /// <returns>技能使用结果</returns>
    Task<SkillUseResult> UsePlayerSkillAsync(Guid gameId, Guid playerId, SkillUseCommand skillCommand);

    /// <summary>
    /// 处理领土占领
    /// 验证占领条件，更新领土归属，计算影响范围
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="territoryCommand">领土命令</param>
    /// <returns>占领处理结果</returns>
    Task<TerritoryClaimResult> ProcessTerritoryClaimAsync(Guid gameId, Guid playerId, TerritoryClaimCommand territoryCommand);

    /// <summary>
    /// 执行游戏规则检查
    /// 检查当前游戏状态是否符合规则要求
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <returns>规则检查结果</returns>
    Task<RuleCheckResult> ExecuteRuleCheckAsync(Guid gameId);

    /// <summary>
    /// 获取玩家可执行的行为列表
    /// 基于当前游戏状态和玩家状态，返回合法的行为选项
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <returns>可用行为列表</returns>
    Task<List<AvailableAction>> GetAvailableActionsAsync(Guid gameId, Guid playerId);

    /// <summary>
    /// 计算行为执行的预期结果
    /// 在不实际执行的情况下，模拟行为的影响
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="actionCommand">行为命令</param>
    /// <returns>预期结果</returns>
    Task<ActionPredictionResult> PredictActionResultAsync(Guid gameId, Guid playerId, IGameActionCommand actionCommand);

    /// <summary>
    /// 获取游戏事件流
    /// 返回指定时间范围内的游戏事件列表
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="since">起始时间</param>
    /// <param name="eventTypes">事件类型过滤</param>
    /// <returns>游戏事件列表</returns>
    Task<GameEventsResult> GetGameEventsAsync(Guid gameId, DateTime? since = null, List<string>? eventTypes = null);

    /// <summary>
    /// 同步玩家位置
    /// 处理玩家位置同步，包括延迟补偿和冲突解决
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="position">新位置</param>
    /// <param name="timestamp">客户端时间戳</param>
    /// <param name="sequence">序列号</param>
    /// <returns>同步结果</returns>
    Task<SyncPositionResult> SyncPlayerPositionAsync(Guid gameId, Guid playerId, Position position, DateTime timestamp, long sequence);

    /// <summary>
    /// 延迟补偿处理
    /// 根据网络延迟调整游戏状态和时间
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="clientTimestamp">客户端时间戳</param>
    /// <param name="actionData">行为数据</param>
    /// <returns>补偿结果</returns>
    Task<LatencyCompensationResult> CompensateLatencyAsync(Guid gameId, Guid playerId, DateTime clientTimestamp, Dictionary<string, object> actionData);
}

/// <summary>
/// 移动命令
/// </summary>
public class MoveCommand : IGameActionCommand
{
    public Guid PlayerId { get; set; }
    public Position NewPosition { get; set; } = new();
    public Direction Direction { get; set; }
    public float Speed { get; set; }
    public DateTime Timestamp { get; set; }
}

/// <summary>
/// 攻击命令
/// </summary>
public class AttackCommand : IGameActionCommand
{
    public Guid PlayerId { get; set; }
    public Guid? TargetPlayerId { get; set; }
    public Position TargetPosition { get; set; } = new();
    public AttackType AttackType { get; set; }
    public float Damage { get; set; }
    public DateTime Timestamp { get; set; }
}

/// <summary>
/// 技能使用命令
/// </summary>
public class SkillUseCommand : IGameActionCommand
{
    public Guid PlayerId { get; set; }
    public string SkillId { get; set; } = string.Empty;
    public Position? TargetPosition { get; set; }
    public Guid? TargetPlayerId { get; set; }
    public Dictionary<string, object> Parameters { get; set; } = new();
    public DateTime Timestamp { get; set; }
}

/// <summary>
/// 领土占领命令
/// </summary>
public class TerritoryClaimCommand : IGameActionCommand
{
    public Guid PlayerId { get; set; }
    public Position Position { get; set; } = new();
    public float Radius { get; set; }
    public TerritoryType TerritoryType { get; set; }
    public DateTime Timestamp { get; set; }
}

/// <summary>
/// 游戏行为命令基接口
/// </summary>
public interface IGameActionCommand
{
    Guid PlayerId { get; set; }
    DateTime Timestamp { get; set; }
}

/// <summary>
/// 移动处理结果
/// </summary>
public class MoveResult
{
    public bool Success { get; set; }
    public Position OldPosition { get; set; } = new();
    public Position NewPosition { get; set; } = new();
    public List<string> Errors { get; set; } = new();
    public List<GameEvent> TriggeredEvents { get; set; } = new();
}

/// <summary>
/// 攻击处理结果
/// </summary>
public class AttackResult
{
    public bool Success { get; set; }
    public float DamageDealt { get; set; }
    public List<Guid> AffectedPlayers { get; set; } = new();
    public List<string> Errors { get; set; } = new();
    public List<GameEvent> TriggeredEvents { get; set; } = new();
}

/// <summary>
/// 收集处理结果
/// </summary>
public class CollectResult
{
    public bool Success { get; set; }
    public string ItemName { get; set; } = string.Empty;
    public int Quantity { get; set; }
    public List<string> Errors { get; set; } = new();
    public List<GameEvent> TriggeredEvents { get; set; } = new();
}

/// <summary>
/// 技能使用结果
/// </summary>
public class SkillUseResult
{
    public bool Success { get; set; }
    public string SkillId { get; set; } = string.Empty;
    public TimeSpan CooldownRemaining { get; set; }
    public List<Guid> AffectedPlayers { get; set; } = new();
    public List<string> Errors { get; set; } = new();
    public List<GameEvent> TriggeredEvents { get; set; } = new();
}

/// <summary>
/// 领土占领结果
/// </summary>
public class TerritoryClaimResult
{
    public bool Success { get; set; }
    public Guid TerritoryId { get; set; }
    public float TerritoryGained { get; set; }
    public float TerritoryLost { get; set; }
    public float NewTotalArea { get; set; }
    public int BonusScore { get; set; }
    public List<Guid> AffectedPlayers { get; set; } = new();
    public List<string> Messages { get; set; } = new();
    public List<string> Errors { get; set; } = new();
    public List<GameEvent> TriggeredEvents { get; set; } = new();
}

/// <summary>
/// 规则检查结果
/// </summary>
public class RuleCheckResult
{
    public bool IsValid { get; set; }
    public List<string> Violations { get; set; } = new();
    public List<string> Warnings { get; set; } = new();
    public List<GameEvent> TriggeredEvents { get; set; } = new();
}

/// <summary>
/// 可用行为
/// </summary>
public class AvailableAction
{
    public string ActionId { get; set; } = string.Empty;
    public string ActionName { get; set; } = string.Empty;
    public ActionType ActionType { get; set; }
    public bool IsAvailable { get; set; }
    public string? DisabledReason { get; set; }
    public TimeSpan? CooldownRemaining { get; set; }
    public Dictionary<string, object> Parameters { get; set; } = new();
}

/// <summary>
/// 游戏事件流结果
/// </summary>
public class GameEventsResult
{
    public bool Success { get; set; }
    public List<GameEvent> Events { get; set; } = new();
    public DateTime LastEventTime { get; set; }
    public int TotalEvents { get; set; }
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 位置同步结果
/// </summary>
public class SyncPositionResult
{
    public bool Success { get; set; }
    public Position AuthoritativePosition { get; set; } = new();
    public DateTime ServerTimestamp { get; set; }
    public long AcknowledgedSequence { get; set; }
    public float Latency { get; set; }
    public List<string> Conflicts { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 延迟补偿结果
/// </summary>
public class LatencyCompensationResult
{
    public bool Success { get; set; }
    public float EstimatedLatency { get; set; }
    public DateTime CompensatedTimestamp { get; set; }
    public Dictionary<string, object> AdjustedData { get; set; } = new();
    public List<string> Corrections { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 行为预测结果
/// </summary>
public class ActionPredictionResult
{
    public bool CanExecute { get; set; }
    public float SuccessProbability { get; set; }
    public List<string> PredictedEffects { get; set; } = new();
    public List<string> Risks { get; set; } = new();
    public Dictionary<string, object> PredictedChanges { get; set; } = new();
}

/// <summary>
/// 游戏事件
/// </summary>
public class GameEvent
{
    public string EventType { get; set; } = string.Empty;
    public Guid? PlayerId { get; set; }
    public string Description { get; set; } = string.Empty;
    public DateTime Timestamp { get; set; }
    public Dictionary<string, object> Data { get; set; } = new();
}

/// <summary>
/// 位置信息
/// </summary>
public class Position
{
    public float X { get; set; }
    public float Y { get; set; }
    public float Z { get; set; }
}

/// <summary>
/// 方向枚举
/// </summary>
public enum Direction
{
    North, South, East, West, NorthEast, NorthWest, SouthEast, SouthWest
}

/// <summary>
/// 攻击类型
/// </summary>
public enum AttackType
{
    Melee, Ranged, Area, Special
}

/// <summary>
/// 领土类型
/// </summary>
public enum TerritoryType
{
    Basic,      // 基础领土
    Fortress,   // 要塞领土  
    Resource,   // 资源领土
    Strategic,  // 战略领土
    Circular    // 圆形领土（画线圈地专用）
}

/// <summary>
/// 行为类型
/// </summary>
public enum ActionType
{
    Move, Attack, Collect, UseSkill, ClaimTerritory, Defend, Special
}
